package com.hx.setting.model;

import java.util.ArrayList;
import java.util.List;
import static java.lang.System.out;

/**
 * 动态查询条件。
 * Generate Date : 2014-03-16
 * Generate Version : v3.0
 * Generate Name : Honey v3.1 Test
 * Generate User : THINK
 * JDK Version : 1.5
 */
@SuppressWarnings("unchecked")
public abstract class GeneratedCriteria<T extends GeneratedCriteria<?, ?>, F extends Enum<?>>
{

	/** 判断规则。 */
	private List<Criterion>	criteria;

	/** 
	 * 构造方法,在子类范围可视。
	 * 
	 */
	protected GeneratedCriteria()
	{
		super();
		this.criteria = new ArrayList<Criterion>();
	}

	/** 
	 * 验证。
	 * @return  boolean
	 */
	public boolean isValid()
	{
		return this.criteria.size() > 0;
	}

	/** 
	 * @return  java.util.List<Criterion>
	 */
	public List<Criterion> getAllCriteria()
	{
		return this.criteria;
	}

	/** 
	 * @return  java.util.List<Criterion>
	 */
	public List<Criterion> getCriteria()
	{
		return this.criteria;
	}

	/** 
	 * 使用and连接 is null 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @return  T
	 * @see    F
	 */
	public T andIsNull(F field)
	{
		addCriterion( field ,Term.IS_NULL );
		return (T) this;
	}

	/** 
	 * 使用and连接 is not null 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @return  T
	 * @see    F
	 */
	public T andIsNotNull(F field)
	{
		addCriterion( field ,Term.IS_NOT_NULL );
		return (T) this;
	}

	/** 
	 * 使用and连接 = 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  value {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 */
	public T andEqualTo(F field, Object value)
	{
		addCriterion( field ,Term.EQUAL_TO ,value );
		return (T) this;
	}

	/** 
	 * 使用and连接 <> 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  value {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 */
	public T andNotEqualTo(F field, Object value)
	{
		addCriterion( field ,Term.NOT_EQUAL_TO ,value );
		return (T) this;
	}

	/** 
	 * 使用and连接 > 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  value {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 */
	public T andGreaterThan(F field, Object value)
	{
		addCriterion( field ,Term.GREATER_THAN ,value );
		return (T) this;
	}

	/** 
	 * 使用and连接 >= 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  value {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 */
	public T andGreaterThanOrEqualTo(F field, Object value)
	{
		addCriterion( field ,Term.GREATER_THAN_OR_EQUAL_TO ,value );
		return (T) this;
	}

	/** 
	 * 使用and连接 < 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  value {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 */
	public T andLessThan(F field, Object value)
	{
		addCriterion( field ,Term.LESS_THAN ,value );
		return (T) this;
	}

	/** 
	 * 使用and连接 <= 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  value {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 */
	public T andLessThanOrEqualTo(F field, Object value)
	{
		addCriterion( field ,Term.LESS_THAN_OR_EQUAL_TO ,value );
		return (T) this;
	}

	/** 
	 * 使用and连接 in 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  values {@code   List<?>}
	 * @return  T
	 * @see    F
	 * @see    List<?>
	 */
	public T andIn(F field, List<?> values)
	{
		addCriterion( field ,Term.IN ,values );
		return (T) this;
	}

	/** 
	 * 使用and连接 in 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  ...values {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 */
	public T andIn(F field, Object ...values)
	{
		List<Object> list = new ArrayList<Object>();
		for ( Object obj : values )
			list.add( obj );
		andIn( field ,list );
		return (T) this;
	}

	/** 
	 * 使用and连接 not in 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  values {@code   List<?>}
	 * @return  T
	 * @see    F
	 * @see    List<?>
	 */
	public T andNotIn(F field, List<?> values)
	{
		addCriterion( field ,Term.NOT_IN ,values );
		return (T) this;
	}

	/** 
	 * 使用and连接 not in 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  ...values {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 */
	public T andNotIn(F field, Object ...values)
	{
		List<Object> list = new ArrayList<Object>();
		for ( Object obj : values )
			list.add( obj );
		andNotIn( field ,list );
		return (T) this;
	}

	/** 
	 * 使用and连接 between 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  value1 {@code   java.lang.Object}
	 * @param  value2 {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 * @see    java.lang.Object
	 */
	public T andBetween(F field, Object value1, Object value2)
	{
		addCriterion( field ,Term.BETWEEN ,value1 ,value2 );
		return (T) this;
	}

	/** 
	 * 使用and连接 not between 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  value1 {@code   java.lang.Object}
	 * @param  value2 {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 * @see    java.lang.Object
	 */
	public T andNotBetween(F field, Object value1, Object value2)
	{
		addCriterion( field ,Term.NOT_BETWEEN ,value1 ,value2 );
		return (T) this;
	}

	/** 
	 * 使用and连接 like 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  value {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 */
	public T andLike(F field, Object value)
	{
		addCriterion( field ,Term.LIKE ,new StringBuilder().append( "%" ).append( value ).append( "%" ).toString() );
		return (T) this;
	}

	/** 
	 * 使用and连接 not like 条件(select update delete)。
	 * @param  field {@code   F} 数据库字段名称枚举。
	 * @param  value {@code   java.lang.Object}
	 * @return  T
	 * @see    F
	 * @see    java.lang.Object
	 */
	public T andNotLike(F field, Object value)
	{
		addCriterion( field ,Term.NOT_LIKE ,new StringBuilder().append( "%" ).append( value ).append( "%" ).toString() );
		return (T) this;
	}

	/** 
	 * 没有值的查询,SQL语句中只有is null和is not null 两种查询条件。
	 * @param  name {@code   Enum<?>}
	 * @param  term {@code   Term}
	 * @return
	 * @see    Enum<?>
	 * @see    Term
	 */
	public T addCriterion(Enum<?> name, Term term)
	{
		if ( term == null )
		{
			throw new RuntimeException( "Value for condition cannot be null" );
		}
		this.criteria.add( new Criterion( name, term ) );
		return (T) this;
	}

	/** 
	 * 有一个值的查询,例如: > < 等查查询。
	 * @param  name {@code   Enum<?>}
	 * @param  term {@code   Term}
	 * @param  value {@code   java.lang.Object}
	 * @return
	 * @see    Enum<?>
	 * @see    Term
	 * @see    java.lang.Object
	 */
	public T addCriterion(Enum<?> name, Term term, Object value)
	{
		if ( value == null )
		{
			throw new RuntimeException( "Value for " + name + " cannot be null" );
		}
		this.criteria.add( new Criterion( name, term, value ) );
		return (T) this;
	}

	/** 
	 * 有一个值的查询,例如: > < 等查查询。
	 * @param  name {@code   Enum<?>}
	 * @param  term {@code   Term}
	 * @param  value1 {@code   java.lang.Object}
	 * @param  value2 {@code   java.lang.Object}
	 * @return
	 * @see    Enum<?>
	 * @see    Term
	 * @see    java.lang.Object
	 * @see    java.lang.Object
	 */
	public T addCriterion(Enum<?> name, Term term, Object value1, Object value2)
	{
		if ( value1 == null || value2 == null )
		{
			throw new RuntimeException( "Between values  for " + name + " cannot be null" );
		}
		this.criteria.add( new Criterion( name, term, value1, value2 ) );
		return (T) this;
	}

	/** 
	 * 填充条件,不支持in查询.
	 * @param gc
	 * @param term 条件
	 * @param field 字段
	 * @param value1 值1
	 * @param value2 值2,between条件时使用
	 */
	public void fillCriterion(GeneratedCriteria gc, Term term, Enum field, Object value1, Object value2)
	{
		switch ( term )
		{
		// >
		// >=
		// <
		// <=
		// <>
		// !=
		//
			default :
				gc.addCriterion( field ,term ,value1 );
				break;
			case LIKE :
				gc.andLike( field ,value1 );
				break;
			case BETWEEN :
			case NOT_BETWEEN :
				gc.addCriterion( field ,term ,value1 ,value2 );
				break;
			case NOT_LIKE :
				gc.andNotLike( field ,value1 );
				break;
			case IS_NOT_NULL :
			case IS_NULL :
				gc.addCriterion( field ,term );
				break;
		}
	}

	/**
	 * 动态sql语句,生成sql的条件语句的规则.
	 * TestAddInnerClassListener
	 */
	public class Criterion
	{

		/** 判断字段。 */
		private Enum<?>	name;

		/** 判断的条件.例如: = , <> , like 等 。 */
		private Term	term;

		/** 判断的条件。 */
		private String	condition;

		/** 判定的第一个值. */
		private Object	value;

		/** 判定的第二个值. */
		private Object	secondValue;

		/** 条件语句没有判定值。 SQL 92中只用 is null和is not null 两种条件没有判定值。 */
		private boolean	noValue;

		/** 条件语句只有一个判定值。 例如: 等于 , 不等于 , 大于 , 小于等条件只有一个比较值,这个比较之存放在vale中。 */
		private boolean	singleValue;

		/** 两个值的条件(between)。SQL 92只有between条件有两个值,第一个值存放在value中 ,第二个值存放在secondValue中。 */
		private boolean	betweenValue;

		/** 多值条件语句(in 查询)。 */
		private boolean	listValue;

		private String	typeHandler;

		/** 
		 * @param  name {@code   Enum<?>}
		 * @param  term {@code   Term}
		 * 
		 * @see    Enum<?>
		 * @see    Term
		 */
		protected Criterion(Enum<?> name, Term term)
		{
			super();
			this.name = name;
			this.term = term;
			this.typeHandler = null;
			this.noValue = true;
			this.condition = new StringBuilder().append( name ).append( ' ' ).append( term ).append( ' ' ).toString();
		}

		/** 
		 * @param  name {@code   Enum<?>}
		 * @param  term {@code   Term}
		 * @param  value {@code   java.lang.Object}
		 * @param  typeHandler {@code   String}
		 * 
		 * @see    Enum<?>
		 * @see    Term
		 * @see    java.lang.Object
		 * @see    String
		 */
		protected Criterion(Enum<?> name, Term term, Object value, String typeHandler)
		{
			super();
			this.name = name;
			this.term = term;
			this.value = value;
			this.typeHandler = typeHandler;
			if ( value instanceof List<?> )
			{
				this.listValue = true;
			}
			else
			{
				this.singleValue = true;
			}
			this.condition = new StringBuilder().append( name ).append( ' ' ).append( term ).append( ' ' ).toString();
		}

		/** 
		 * @param  name {@code   Enum<?>}
		 * @param  term {@code   Term}
		 * @param  value {@code   java.lang.Object}
		 * 
		 * @see    Enum<?>
		 * @see    Term
		 * @see    java.lang.Object
		 */
		protected Criterion(Enum<?> name, Term term, Object value)
		{
			this( name, term, value, null );
		}

		/** 
		 * @param  name {@code   Enum<?>}
		 * @param  term {@code   Term}
		 * @param  value {@code   java.lang.Object}
		 * @param  secondValue {@code   java.lang.Object}
		 * @param  typeHandler {@code   String}
		 * 
		 * @see    Enum<?>
		 * @see    Term
		 * @see    java.lang.Object
		 * @see    java.lang.Object
		 * @see    String
		 */
		protected Criterion(Enum<?> name, Term term, Object value, Object secondValue, String typeHandler)
		{
			super();
			this.name = name;
			this.term = term;
			this.value = value;
			this.secondValue = secondValue;
			this.typeHandler = typeHandler;
			this.betweenValue = true;
			this.condition = new StringBuilder().append( name ).append( ' ' ).append( term ).append( ' ' ).toString();
		}

		/** 
		 * @param  name {@code   Enum<?>}
		 * @param  term {@code   Term}
		 * @param  value {@code   java.lang.Object}
		 * @param  secondValue {@code   java.lang.Object}
		 * 
		 * @see    Enum<?>
		 * @see    Term
		 * @see    java.lang.Object
		 * @see    java.lang.Object
		 */
		protected Criterion(Enum<?> name, Term term, Object value, Object secondValue)
		{
			this( name, term, value, secondValue, null );
		}

		/** 
		 * 获取{@code name}属性的值
		 * @return  Enum<?>
		 */
		public Enum<?> getName()
		{
			return this.name;
		}

		/** 
		 * 获取{@code term}属性的值
		 * @return  Term
		 */
		public Term getTerm()
		{
			return this.term;
		}

		/** 
		 * 获取{@code condition}属性的值
		 * @return  String
		 */
		public String getCondition()
		{
			return this.condition;
		}

		/** 
		 * 获取{@code value}属性的值
		 * @return  java.lang.Object
		 */
		public Object getValue()
		{
			return this.value;
		}

		/** 
		 * 获取{@code secondValue}属性的值
		 * @return  java.lang.Object
		 */
		public Object getSecondValue()
		{
			return this.secondValue;
		}

		/** 
		 * 获取{@code noValue}属性的值
		 * @return  boolean
		 */
		public boolean getNoValue()
		{
			return this.noValue;
		}

		/** 
		 * 获取{@code singleValue}属性的值
		 * @return  boolean
		 */
		public boolean getSingleValue()
		{
			return this.singleValue;
		}

		/** 
		 * 获取{@code betweenValue}属性的值
		 * @return  boolean
		 */
		public boolean getBetweenValue()
		{
			return this.betweenValue;
		}

		/** 
		 * 获取{@code listValue}属性的值
		 * @return  boolean
		 */
		public boolean getListValue()
		{
			return this.listValue;
		}

		/** 
		 * 获取{@code typeHandler}属性的值
		 * @return  String
		 */
		public String getTypeHandler()
		{
			return this.typeHandler;
		}
	}

	/**
	 * 判断条件
	 * 
	 */
	public enum Term
	{
		/** 
		 * is null 条件
		 */
		IS_NULL( "IS NULL" ),
		/** 
		 * is not null 条件
		 */
		IS_NOT_NULL( "IS NOT NULL" ),
		/** 
		 * = 条件
		 */
		EQUAL_TO( "=" ),
		/** 
		 * <> 条件
		 */
		NOT_EQUAL_TO( "<>" ),
		/** 
		 * > 条件
		 */
		GREATER_THAN( ">" ),
		/** 
		 * >= 条件
		 */
		GREATER_THAN_OR_EQUAL_TO( ">=" ),
		/** 
		 * < 条件
		 */
		LESS_THAN( "<" ),
		/** 
		 * <= 条件
		 */
		LESS_THAN_OR_EQUAL_TO( "<=" ),
		/** 
		 * in 条件
		 */
		IN( "IN" ),
		/** 
		 * not in 条件
		 */
		NOT_IN( "NOT IN" ),
		/** 
		 * between 条件
		 */
		BETWEEN( "BETWEEN" ),
		/** 
		 * not between 条件
		 */
		NOT_BETWEEN( "NOT BETWEEN" ),
		/** 
		 * like 条件
		 */
		LIKE( "LIKE" ),
		/** 
		 * not like 条件
		 */
		NOT_LIKE( "NOT LIKE" );

		private final String	value;

		private final int		code;

		/** 
		 * @param  value {@code   String}
		 * 
		 * @see    String
		 */
		private Term(String value)
		{
			this.value = value;
			this.code = value.hashCode();
		}

		public static Term getInstance(String term)
		{
			Term answer = EQUAL_TO;
			if ( term != null )
			{
				term = com.hx.setting.utils.StringUtils.deleteWhitespace( term );
				if ( term.length() > 0 )
				{
					int hash = term.toUpperCase().hashCode();
					switch ( hash )
					{
						case 61 : // =
							answer = EQUAL_TO;
							break;
						case 60 : //<
							answer = LESS_THAN;
							break;
						case 62 : //>
							answer = GREATER_THAN;
							break;
						case 1983 : //>=
							answer = GREATER_THAN_OR_EQUAL_TO;
							break;
						case 1921 : //<=
							answer = LESS_THAN_OR_EQUAL_TO;
							break;
						case 501348328 : //BETWEEN
							answer = BETWEEN;
							break;
						case 2336663 : //LIKE
							answer = LIKE;
							break;
						case -1447541558 : //NOT LIKE
							answer = NOT_LIKE;
							break;
						case 1084 : //!=
							answer = NOT_EQUAL_TO;
							break;
						case 1922 : //<>
							answer = NOT_EQUAL_TO;
							break;
						case -2125979215 : // IS NULL
							answer = IS_NULL;
							break;
						case -1623290288 : // IS NOT NULL
							answer = IS_NOT_NULL;
							break;
						case 1665362389 : //NOT BETWEEN
							answer = NOT_BETWEEN;
							break;
						case 2341 : //IN
							answer = IN;
							break;
					}
				}
			}
			return answer;
		}

		/** 
		 * @return  String
		 */
		@Override
		public String toString()
		{
			return this.value;
		}
	}
}
/* Honey v3.1 Test - version:1 - OriginalChecksum:Bc93c13677f247455295ee2a00dbfc51b (do not edit this line) */
